﻿using System.Security.AccessControl;
using System.Text;
using Microsoft.Extensions.FileProviders;

namespace FrameworkCore.Utilities;
/// <summary>
/// 文件提供者的抽象
/// </summary>
public partial interface INetModulerFileProvider : IFileProvider
{
    /// <summary>
    /// 将字符串数组组合成路径
    /// </summary>
    /// <param name="paths">路径的各部分数组</param>
    /// <returns>组合后的路径</returns>
    string Combine(params string[] paths);

    /// <summary>
    /// 创建指定路径中的所有目录和子目录（除非它们已经存在）
    /// </summary>
    /// <param name="path">要创建的目录</param>
    void CreateDirectory(string path);

    /// <summary>
    /// 在指定路径创建文件
    /// </summary>
    /// <param name="path">要创建的文件的路径和名称</param>
    void CreateFile(string path);

    /// <summary>
    /// 深度优先递归删除，处理在Windows资源管理器中打开的后代目录。
    /// </summary>
    /// <param name="path">目录路径</param>
    void DeleteDirectory(string path);

    /// <summary>
    /// 删除指定的文件
    /// </summary>
    /// <param name="filePath">要删除的文件名。不支持通配符字符。</param>
    void DeleteFile(string filePath);

    /// <summary>
    /// 确定指定路径是否引用磁盘上的现有目录
    /// </summary>
    /// <param name="path">要测试的路径</param>
    /// <returns>
    /// 如果路径引用现有目录，则为true；如果目录不存在或在尝试确定指定文件是否存在时发生错误，则为false
    /// </returns>
    bool DirectoryExists(string path);

    /// <summary>
    /// 将文件或目录及其内容移动到新位置
    /// </summary>
    /// <param name="sourceDirName">要移动的文件或目录的路径</param>
    /// <param name="destDirName">
    /// sourceDirName 的新位置的路径。如果 sourceDirName 是文件，则 destDirName 也必须是文件名
    /// </param>
    void DirectoryMove(string sourceDirName, string destDirName);

    /// <summary>
    /// 返回指定路径中符合搜索模式的文件名的可枚举集合，并可选择搜索子目录
    /// </summary>
    /// <param name="directoryPath">要搜索的目录路径</param>
    /// <param name="searchPattern">
    /// 与路径中文件名匹配的搜索字符串。此参数可以包含有效的文本路径和通配符（* 和 ?），但不支持正则表达式
    /// </param>
    /// <param name="topDirectoryOnly">
    /// 指定是搜索当前目录还是当前目录及所有子目录
    /// </param>
    /// <returns>
    /// 包含路径中指定目录中与指定搜索模式匹配的文件的完整名称（包括路径）的可枚举集合
    /// </returns>
    IEnumerable<string> EnumerateFiles(string directoryPath, string searchPattern, bool topDirectoryOnly = true);

    /// <summary>
    /// 将现有文件复制到新文件。允许覆盖同名文件
    /// </summary>
    /// <param name="sourceFileName">要复制的文件</param>
    /// <param name="destFileName">目标文件的名称。这不能是一个目录</param>
    /// <param name="overwrite">如果可以覆盖目标文件，则为true；否则为false</param>
    void FileCopy(string sourceFileName, string destFileName, bool overwrite = false);

    /// <summary>
    /// 确定指定文件是否存在
    /// </summary>
    /// <param name="filePath">要检查的文件</param>
    /// <returns>
    /// 如果调用者具有所需权限且路径包含现有文件的名称，则为true；否则为false
    /// </returns>
    bool FileExists(string filePath);

    /// <summary>
    /// 获取文件的长度（以字节为单位），如果是目录或不存在的文件则返回-1
    /// </summary>
    /// <param name="path">文件路径</param>
    /// <returns>文件的长度</returns>
    long FileLength(string path);

    /// <summary>
    /// 将指定的文件移动到新位置，并提供指定新文件名的选项
    /// </summary>
    /// <param name="sourceFileName">要移动的文件名。可以包括相对或绝对路径</param>
    /// <param name="destFileName">文件的新路径和名称</param>
    void FileMove(string sourceFileName, string destFileName);

    /// <summary>
    /// 返回目录的绝对路径
    /// </summary>
    /// <param name="paths">路径的各个部分组成的数组</param>
    /// <returns>目录的绝对路径</returns>
    string GetAbsolutePath(params string[] paths);

    /// <summary>
    /// 获取指定目录的访问控制列表（ACL）条目的 System.Security.AccessControl.DirectorySecurity 对象
    /// </summary>
    /// <param name="path">包含描述文件访问控制列表（ACL）信息的 System.Security.AccessControl.DirectorySecurity 对象的目录的路径</param>
    /// <returns>封装了指定路径参数描述的文件的访问控制规则的对象</returns>
    DirectorySecurity GetAccessControl(string path);

    /// <summary>
    /// 返回指定文件或目录的创建日期和时间
    /// </summary>
    /// <param name="path">要获取创建日期和时间信息的文件或目录</param>
    /// <returns>
    /// 设置为指定文件或目录的创建日期和时间的 System.DateTime 结构。此值以本地时间表示
    /// </returns>
    DateTime GetCreationTime(string path);

    /// <summary>
    /// 返回指定目录中与指定搜索模式匹配的子目录（包括其路径）
    /// </summary>
    /// <param name="path">要搜索的目录路径</param>
    /// <param name="searchPattern">
    /// 用于与路径中子目录的名称匹配的搜索字符串。此参数可以包含有效的文本路径和通配符（* 和 ?），但不支持正则表达式
    /// </param>
    /// <param name="topDirectoryOnly">
    /// 指定是搜索当前目录还是当前目录及所有子目录
    /// </param>
    /// <returns>
    /// 包含与指定条件匹配的子目录的完整名称（包括路径）数组，如果未找到任何目录，则返回空数组
    /// </returns>
    string[] GetDirectories(string path, string searchPattern = "", bool topDirectoryOnly = true);

    /// <summary>
    /// Returns the directory information for the specified path string
    /// </summary>
    /// <param name="path">The path of a file or directory</param>
    /// <returns>
    /// Directory information for path, or null if path denotes a root directory or is null. Returns
    /// System.String.Empty if path does not contain directory information
    /// </returns>
    string GetDirectoryName(string path);

    /// <summary>
    /// Returns the directory name only for the specified path string
    /// </summary>
    /// <param name="path">The path of directory</param>
    /// <returns>The directory name</returns>
    string GetDirectoryNameOnly(string path);

    /// <summary>
    /// Returns the extension of the specified path string
    /// </summary>
    /// <param name="filePath">The path string from which to get the extension</param>
    /// <returns>The extension of the specified path (including the period ".")</returns>
    string GetFileExtension(string filePath);

    /// <summary>
    /// Returns the file name and extension of the specified path string
    /// </summary>
    /// <param name="path">The path string from which to obtain the file name and extension</param>
    /// <returns>The characters after the last directory character in path</returns>
    string GetFileName(string path);

    /// <summary>
    /// Returns the file name of the specified path string without the extension
    /// </summary>
    /// <param name="filePath">The path of the file</param>
    /// <returns>The file name, minus the last period (.) and all characters following it</returns>
    string GetFileNameWithoutExtension(string filePath);

    /// <summary>
    /// Returns the names of files (including their paths) that match the specified search
    /// pattern in the specified directory, using a value to determine whether to search subdirectories.
    /// </summary>
    /// <param name="directoryPath">The path to the directory to search</param>
    /// <param name="searchPattern">
    /// The search string to match against the names of files in path. This parameter
    /// can contain a combination of valid literal path and wildcard (* and ?) characters
    /// , but doesn't support regular expressions.
    /// </param>
    /// <param name="topDirectoryOnly">
    /// Specifies whether to search the current directory, or the current directory and all
    /// subdirectories
    /// </param>
    /// <returns>
    /// An array of the full names (including paths) for the files in the specified directory
    /// that match the specified search pattern, or an empty array if no files are found.
    /// </returns>
    string[] GetFiles(string directoryPath, string searchPattern = "", bool topDirectoryOnly = true);

    /// <summary>
    /// Returns the date and time the specified file or directory was last accessed
    /// </summary>
    /// <param name="path">The file or directory for which to obtain access date and time information</param>
    /// <returns>A System.DateTime structure set to the date and time that the specified file</returns>
    DateTime GetLastAccessTime(string path);

    /// <summary>
    /// Returns the date and time the specified file or directory was last written to
    /// </summary>
    /// <param name="path">The file or directory for which to obtain write date and time information</param>
    /// <returns>
    /// A System.DateTime structure set to the date and time that the specified file or directory was last written to.
    /// This value is expressed in local time
    /// </returns>
    DateTime GetLastWriteTime(string path);

    /// <summary>
    /// Returns the date and time, in coordinated universal time (UTC), that the specified file or directory was last
    /// written to
    /// </summary>
    /// <param name="path">The file or directory for which to obtain write date and time information</param>
    /// <returns>
    /// A System.DateTime structure set to the date and time that the specified file or directory was last written to.
    /// This value is expressed in UTC time
    /// </returns>
    DateTime GetLastWriteTimeUtc(string path);

    /// <summary>
    /// Creates or opens a file at the specified path for read/write access
    /// </summary>
    /// <param name="path">The path and name of the file to create</param>
    /// <returns>A <see cref="FileStream"/> that provides read/write access to the file specified in <paramref name="path"/></returns>
    FileStream GetOrCreateFile(string path);

    /// <summary>
    /// Retrieves the parent directory of the specified path
    /// </summary>
    /// <param name="directoryPath">The path for which to retrieve the parent directory</param>
    /// <returns>The parent directory, or null if path is the root directory, including the root of a UNC server or share name</returns>
    string GetParentDirectory(string directoryPath);

    /// <summary>
    /// Gets a virtual path from a physical disk path.
    /// </summary>
    /// <param name="path">The physical disk path</param>
    /// <returns>The virtual path. E.g. "~/bin"</returns>
    string GetVirtualPath(string path);

    /// <summary>
    /// Checks if the path is directory
    /// </summary>
    /// <param name="path">Path for check</param>
    /// <returns>True, if the path is a directory, otherwise false</returns>
    bool IsDirectory(string path);

    /// <summary>
    /// Maps a virtual path to a physical disk path.
    /// </summary>
    /// <param name="path">The path to map. E.g. "~/bin"</param>
    /// <returns>The physical path. E.g. "c:\inetpub\wwwroot\bin"</returns>
    string MapPath(string path);

    /// <summary>
    /// Reads the contents of the file into a byte array
    /// </summary>
    /// <param name="filePath">The file for reading</param>
    /// <returns>
    /// A task that represents the asynchronous operation
    /// The task result contains a byte array containing the contents of the file
    /// </returns>
    Task<byte[]> ReadAllBytesAsync(string filePath);

    /// <summary>
    /// Opens a file, reads all lines of the file with the specified encoding, and then closes the file.
    /// </summary>
    /// <param name="path">The file to open for reading</param>
    /// <param name="encoding">The encoding applied to the contents of the file</param>
    /// <returns>
    /// A task that represents the asynchronous operation
    /// The task result contains a string containing all lines of the file
    /// </returns>
    Task<string> ReadAllTextAsync(string path, Encoding encoding);

    /// <summary>
    /// Opens a file, reads all lines of the file with the specified encoding, and then closes the file.
    /// </summary>
    /// <param name="path">The file to open for reading</param>
    /// <param name="encoding">The encoding applied to the contents of the file</param>
    /// <returns>A string containing all lines of the file</returns>
    string ReadAllText(string path, Encoding encoding);

    /// <summary>
    /// Writes the specified byte array to the file
    /// </summary>
    /// <param name="filePath">The file to write to</param>
    /// <param name="bytes">The bytes to write to the file</param>
    /// <returns>A task that represents the asynchronous operation</returns>
    Task WriteAllBytesAsync(string filePath, byte[] bytes);

    /// <summary>
    /// Creates a new file, writes the specified string to the file using the specified encoding,
    /// and then closes the file. If the target file already exists, it is overwritten.
    /// </summary>
    /// <param name="path">The file to write to</param>
    /// <param name="contents">The string to write to the file</param>
    /// <param name="encoding">The encoding to apply to the string</param>
    /// <returns>A task that represents the asynchronous operation</returns>
    Task WriteAllTextAsync(string path, string contents, Encoding encoding);

    /// <summary>
    /// Creates a new file, writes the specified string to the file using the specified encoding,
    /// and then closes the file. If the target file already exists, it is overwritten.
    /// </summary>
    /// <param name="path">The file to write to</param>
    /// <param name="contents">The string to write to the file</param>
    /// <param name="encoding">The encoding to apply to the string</param>
    void WriteAllText(string path, string contents, Encoding encoding);

    /// <summary>
    /// Gets or sets the absolute path to the directory that contains the web-servable application content files.
    /// </summary>
    string WebRootPath { get; }
}